package xq.gwt.ui.widgets.entity;

import java.util.ArrayList;
import java.util.Arrays;


import xq.gwt.mvc.model.EntityModel;
import xq.gwt.mvc.model.PropertyGroup;
import xq.gwt.mvc.model.PropertyModel;
import xq.gwt.ui.widgets.command.CommandListPresenter;
import xq.gwt.ui.widgets.command.ToolStripCommandListPresenter;
import xq.gwt.ui.widgets.property.FormItemPropertyPresenter;
import xq.gwt.ui.widgets.property.PropertyListPresenter;
import com.smartgwt.client.types.VerticalAlignment;
import com.smartgwt.client.widgets.Canvas;
import com.smartgwt.client.widgets.form.DynamicForm;
import com.smartgwt.client.widgets.layout.HLayout;
import com.smartgwt.client.widgets.layout.Layout;
import com.smartgwt.client.widgets.layout.VLayout;


public class FormEntityPresenter implements EntityPresenter{
	protected DynamicForm form;
	protected EntityModel entity;
	protected PropertyListPresenter propPresenter;
	protected VLayout mainLayout = new VLayout();
	protected HLayout buttonLayout = new HLayout();
	protected CommandListPresenter commandPresenter;
	protected CommandPosition commandPosition = CommandPosition.Top;
	protected PropertyGroup[] propertyGroups;
	protected Canvas fieldCanvas;
	protected int numCols;
	protected DynamicForm[] groupForms;
	protected ArrayList<FormItemPropertyPresenter> propertyPresenters = new ArrayList<FormItemPropertyPresenter>();
	
	public FormEntityPresenter(){
		form = new DynamicForm();
		commandPresenter = new ToolStripCommandListPresenter();
		init();
	}
	
	public FormEntityPresenter(DynamicForm form){
		this.form = form;
		commandPresenter = new ToolStripCommandListPresenter();
		init();
	}
	
	public FormEntityPresenter(CommandListPresenter commandListPresenter){
		form = new DynamicForm();
		this.commandPresenter = commandListPresenter;
		init();
	}
	
	public FormEntityPresenter(DynamicForm form, CommandListPresenter commandListPresenter){
		this.form = form;
		this.commandPresenter = commandListPresenter;
		init();
	}
	
	protected void init(){		
		mainLayout.setAlign(VerticalAlignment.TOP);	
		fieldCanvas = form;
	}
	
	public void setEntity(EntityModel entity){		
		this.entity = entity;
		form.setTitle(entity.getTitle());
		if(form.getIsGroup())
			form.setGroupTitle(entity.getTitle());
		//show fields		
		if (propertyGroups == null) {
			propPresenter = new PropertyListPresenter(form);
			propPresenter.setProperties(this.entity.getProperties());
			if(numCols != 0){
				form.setNumCols(numCols);
			}
			if(propPresenter.getPopertyPresenters() != null){
				propertyPresenters.addAll(Arrays.asList(propPresenter.getPopertyPresenters()));
			}
			
			fieldCanvas = form;
		} else {
			propPresenter = null;
			Layout groupLayout = buildFieldGroups();
			fieldCanvas = groupLayout;
		}
		
		//show commands			
		if(this.entity != null){
			commandPresenter.setCommands(this.entity.getCommands());
			buttonLayout.setMembers(commandPresenter.getCanvas());
		}					
	}

	public Canvas getCanvas() {		
		switch (commandPosition) {
		case Top:
			if(!mainLayout.contains(buttonLayout))
				mainLayout.addMember(buttonLayout);
			if(!mainLayout.contains(fieldCanvas))
				mainLayout.addMember(fieldCanvas);			
			break;
		case Bottom:			
			if(!mainLayout.contains(fieldCanvas))
				mainLayout.addMember(fieldCanvas);
			if(!mainLayout.contains(buttonLayout))
				mainLayout.addMember(buttonLayout);			
			break;
		default:
			break;
		}
		
				
		return mainLayout;
	}
	
	 
	
	public PropertyGroup[] getPropertyGroups() {
		return propertyGroups;
	}

	public void setPropertyGroups(PropertyGroup[] propertyGroups) {
		this.propertyGroups = propertyGroups;
	}

	public CommandPosition getCommandPosition() {
		return commandPosition;
	}

	public void setCommandPosition(CommandPosition commandPosition) {
		this.commandPosition = commandPosition;
	}

	public enum CommandPosition {
		Top, Bottom;
	}
	
	private Layout buildFieldGroups(){
		VLayout groupLayout = new VLayout();
		groupLayout.setWidth100();
		groupLayout.setHeight100();
		if(propertyGroups == null)
			return groupLayout;
		if(propertyGroups.length == 0)
			return groupLayout;
		if(this.entity == null)
			return groupLayout;
		if(this.entity.getProperties() == null)
			return groupLayout;
		
		
		groupForms = new DynamicForm[propertyGroups.length];
		for (int i = 0; i < propertyGroups.length; i++) {
			//Create Presenter
			PropertyListPresenter propPresenter = new PropertyListPresenter();
			propPresenter.getForm().setGroupTitle(propertyGroups[i].groupName);
			propPresenter.getForm().setIsGroup(true);
			Integer[] propIndexes = propertyGroups[i].propertyIndexes;
			
			//Extract Properties
			PropertyModel[] groupProps = new PropertyModel[propIndexes.length];
			for (int j = 0; j < propIndexes.length; j++) {
				try {
					groupProps[j] = this.entity.getProperties()[propIndexes[j]];
				} catch (IndexOutOfBoundsException e) {
					//do nothing;
				}				 
			}
			
			//Add group Presenter
			if(numCols != 0){
				propPresenter.getForm().setNumCols(numCols);
			}
			
			propPresenter.setProperties(groupProps);
			if(propPresenter.getPopertyPresenters() != null){
				propertyPresenters.addAll(Arrays.asList(propPresenter.getPopertyPresenters()));
			}
			groupLayout.addMember(propPresenter.getForm());	
			groupForms[i] = propPresenter.getForm();
		}
		return groupLayout;		
	}
	
	public int getNumCols() {
		return numCols;
	}

	public void setNumCols(int numCols) {
		this.numCols = numCols;
	}
	
	public DynamicForm getForm(){
		return form;
	}
	
	public DynamicForm[] getGroupForms(){
		return groupForms;
	}

	public FormItemPropertyPresenter[] getPropertyPresenters() {
		FormItemPropertyPresenter[] propPresentersArray = new FormItemPropertyPresenter[propertyPresenters.size()];
		propertyPresenters.toArray(propPresentersArray);
		return propPresentersArray;
	}
	
	
}
